<template>
  <div class="render-target-prc">
    <!-- threejs官网的 ‘一些有用的链接’ -->
    <!-- uv动画 -->
    <div class="canvas" ref="canvas"></div>
  </div>
</template>

<script lang="ts">
import { Vue, Options } from 'vue-property-decorator';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
const resource = import.meta.globEager('../../assets/*');
const scene = new THREE.Scene();
scene.background = new THREE.Color('black');
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 50, 250);
scene.add(camera);
{
  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(-1, 2, 4);
  scene.add(light);
}
{
  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(2, -5, -3);
  scene.add(light);
}
const renderer = new THREE.WebGLRenderer({
  alpha: true,
  antialias: true,
});
renderer.debug.checkShaderErrors = false;
renderer.setClearColor(new THREE.Color(), 0);
renderer.setPixelRatio(750 / window.innerWidth);

let clock!: THREE.Clock;

const texture = new THREE.TextureLoader().load(resource['../../assets/fire.jpg'].default);
const VertexShader = `
    varying vec2 texcoord;
    void main(){
      gl_Position = projectionMatrix * modelViewMatrix *vec4(position,4);
      texcoord = uv;
    }
`;
const FragmentShader = `
    varying vec2 texcoord;
    uniform sampler2D _MainTex;
    uniform float _Time;
    uniform float _HAmount;
    uniform float _VAmount;
    uniform float _Speed;
    void main(){
      float time = floor(_Time*_Speed);
      float row = floor(time/_HAmount);
      float column = time - row*_HAmount;

      vec2 uv = texcoord +vec2(column,-row);
      uv.x /=_HAmount;
      uv.y /=_VAmount;

      // fract(x) = x - floor(x)
      uv.x = fract(uv.x);
      uv.y = fract(uv.y);

      // 纹理查询的最终目的是从sampler中提取指定坐标的颜色信息
      vec4 c= texture2D(_MainTex,uv);
      gl_FragColor = c;
    }
`;
const uniforms = {
  _Time: {
    value: 0.0,
  },
  _MainTex: {
    value: texture,
  },
  _Speed: {
    value: 10,
  },
  _HAmount: {
    value: 8,
  },
  _VAmount: {
    value: 4,
  },
};
@Options({ components: {} })
export default class SpiralCircle extends Vue {
  public rect: DOMRect|null = null;

  public resizeRendererToDisplaySize(renderer: THREE.WebGLRenderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needSize = canvas.width !== width || canvas.height !== height;
    if (needSize) {
      renderer.setSize(width, height, false);
    }
    return needSize;
  }
  public mounted() {
    this.rect = (this.$el as HTMLElement).getBoundingClientRect();
    renderer.setSize(this.rect.width, this.rect.height, false);
    (this.$refs.canvas as HTMLDivElement).append(renderer.domElement);

    clock = new THREE.Clock();
    const geometry = new THREE.PlaneGeometry(80, 80);
    const material = new THREE.ShaderMaterial({
      uniforms,
      vertexShader: VertexShader,
      fragmentShader: FragmentShader,
      transparent: true,
    });
    const mesh = new THREE.Mesh(geometry, material);
    mesh.rotation.x = -Math.PI / 2;
    scene.add(mesh);
    camera.position.z = 5;

    renderer.setAnimationLoop((time) => {
      // getDelta() 获取自 .oldTime 设置后到当前的秒数 同时将 .oldTime 设置为当前时间
      const deltaTime = clock.getDelta();
      material.uniforms._Time.value += deltaTime;
      renderer.render(scene, camera);
    });

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableZoom = false;
  }
}
</script>

<style lang="postcss" scoped>
  .render-target-prc{
    touch-action: none;
    position: absolute;
    left: 0;top: 0;
    width: 100%;height: 100%;
    background: #98bbd1;
    .canvas{
      position: absolute;
      left: 0;top: 0;
      width: 100%;height: 100%;
       :deep(canvas){
          width: 100%;height: 100%;
       }
    }
  }
</style>
